home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
modula.arc
/
POLYSORT.MOD
< prev
next >
Wrap
Text File
|
1985-05-30
|
5KB
|
211 lines
(* Polyphase sort program. There are n-1 source files for
merging and a single output file. The destination of the
merged data chabges, when a certain number of runs has been
distributed. This number is computed according to a
Fibonacci distribution. *)
MODULE polysort;
FROM InOut IMPORT WriteCard;
FROM Terminal IMPORT WriteString, WriteLn, Read;
FROM FileSystem IMPORT File, Lookup, Create, Reset, SetPos, GetPos, Response, Close;
FROM ByteBlockIO IMPORT ReadByteBlock, WriteByteBlock;
CONST n = 6; (* # of files *)
numrecs = 10;
TYPE item = RECORD
key: CARDINAL;
END;
tapeno = [1..n];
VAR leng,high,low,rand: CARDINAL;
eot: BOOLEAN;
buf,next: item;
f0: File;
f: ARRAY [1..n] OF File;
ch: CHAR;
PROCEDURE list(VAR f: File; n: tapeno);
VAR z: CARDINAL;
BEGIN
z := 0;
WriteLn; WriteString(' tape ');
WriteCard(n,2); WriteLn;
LOOP
ReadByteBlock(f,buf);
IF f.eof THEN EXIT END;
WriteCard(buf.key,5);
INC(z);
IF z = 15 THEN WriteLn; z := 0 END
END;
WriteLn;
Reset(f)
END list;
PROCEDURE polyphasesort;
VAR i,j,mx,tn,dn,x,min,z: CARDINAL(* tapeno *);
k,level:CARDINAL;
a,d,last,t,ta: ARRAY tapeno OF CARDINAL;
(* a[j] = ideal # of runs on file j *)
(* d[j] = # of dummy runs on file *)
(* last[j] = key of tail item on tape *)
(* t,ta = mappings of tape #'s *)
PROCEDURE selectfile;
VAR i: tapeno;
z: CARDINAL;
BEGIN
IF d[j] < d[j+1] THEN
INC(j)
ELSE
IF d[j] = 0 THEN
INC(level); z := a[1];
FOR i := 1 TO n-1 DO
d[i] := z + a[i+1] - a[i];
a[i] := z + a[i+1]
END
END;
j := 1
END;
DEC(d[j]);
END selectfile;
PROCEDURE copyrun;
VAR buf,next: item;
high,low : CARDINAL;
BEGIN (*copy one run from x to y*)
ReadByteBlock(f0,next);
REPEAT
buf := next;
IF NOT f0.eof THEN
WriteByteBlock(f[j],buf);
GetPos(f0,high,low);
ReadByteBlock(f0,next);
END;
UNTIL f0.eof OR (buf.key > next.key);
IF NOT f0.eof THEN SetPos(f0,high,low) END;
last[j] := buf.key
END copyrun;
BEGIN (* polyphasesort *)
FOR i := 1 TO n(* -1 *) DO
a[i] := 1; d[i] := 1;
Create(f[i],'DK.')
END;
level := 1; j := 1;
a[n] := 0; d[n] := 0;
REPEAT
selectfile;
copyrun;
UNTIL f0.eof OR (j = n-1);
LOOP
IF f0.eof THEN EXIT END;
selectfile;
GetPos(f0,high,low);
ReadByteBlock(f0,next);
SetPos(f0,high,low);
IF last[j] <= next.key THEN
copyrun;
IF f0.eof THEN d[j] := d[j]+1 ELSE copyrun END
ELSE copyrun
END
END;
FOR i := 1 TO n-1 DO Reset(f[i]) END;
FOR i := 1 TO n DO t[i] := i END;
REPEAT
z := a[n-1]; d[n] := 0;
Close(f[t[n]]); Create(f[t[n]],'DK.');
WriteString(' level'); WriteCard(level,4); WriteLn;
WriteString(' tape'); WriteCard(t[n],4); WriteLn;
FOR i := 1 TO n DO
WriteCard(t[i],6);
WriteCard(a[i],6);
WriteCard(d[i],6);
WriteLn
END;
REPEAT
k := 0;
FOR i := 1 TO n-1 DO
IF d[i] > 0 THEN
DEC(d[i])
ELSE
INC(k);
ta[k] := t[i]
END
END;
IF k = 0 THEN
INC(d[n])
ELSE
REPEAT
i := 1; mx := 1;
GetPos(f[ta[1]],high,low);
ReadByteBlock(f[ta[1]],next);
SetPos(f[ta[1]],high,low);
min := next.key;
WHILE i < k DO
INC(i);
GetPos(f[ta[i]],high,low);
ReadByteBlock(f[ta[i]],next);
SetPos(f[ta[i]],high,low);
x := next.key;
IF x < min THEN
min := x;
mx := i
END
END;
(* ta[mx] has minimal element, move it to t[j] *)
ReadByteBlock(f[ta[mx]],buf);
WriteByteBlock(f[t[n]],buf);
GetPos(f[ta[mx]],high,low);
ReadByteBlock(f[ta[mx]],next);
eot := f[ta[mx]].eof;
SetPos(f[ta[mx]],high,low);
IF (buf.key > next.key) OR eot THEN
ta[mx] := ta[k];
DEC(k)
END
UNTIL k = 0;
END;
DEC(z);
UNTIL z = 0;
Reset(f[t[n]]);
list(f[t[n]],t[n]);
tn := t[n];
dn := d[n];
z := a[n-1];
FOR i := n TO 2 BY -1 DO
t[i] := t[i-1];
d[i] := d[i-1];
a[i] := a[i-1] - z
END;
t[1] := tn;
d[1] := dn;
a[1] := z;
DEC(level)
UNTIL level = 0;
END polyphasesort;
BEGIN
leng := numrecs;
Lookup(f0,'tmp.TEXT',TRUE);
IF f0.res # done THEN WriteString(' File not opened. ') END;
REPEAT
buf.key := leng;
WriteCard(buf.key,4);
WriteByteBlock(f0,buf);
DEC(leng);
IF (leng MOD 20) = 0 THEN WriteLn END;
UNTIL leng = 0;
WriteLn;
Reset(f0); list(f0,1);
polyphasesort;
FOR low := 1 TO n-1 DO Close(f[low]) END;
END polysort.